#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <qmainwindow.h>
#include <qtcpsocket.h>
#include <qsqlquery.h>
#include <qsqldatabase.h>
#include <qdebug.h>
#include <qtextbrowser.h>
#include <qtimer.h>
#include <QTime>
#include <qfile.h>
#include <qdir.h>
#include <QProcess>
#include "isi.h"

/**
@startuml
title Алгоритм работы клиента часть 1
:Запуск;
repeat:Ожидание нажатия кнопки;
    if(Кнопка нажата?) then(Нет)
    else(Да)
        :Подключение к серверу;
        :Настройка сведений о клиенте;
        :Ожидание срабатывания readyRead;
            while (Сработал?) is (Нет)
        : Ожидание срабатывания readyRead;
    endwhile (Да)
        : Создание бинарного потока
        для чтения. Он = false;
        if (Состояние потока - норма?) then (Нет)
        #pink: Вывести ошибку;
        end;
        else (Да)
        : Получение сообщения;
        : Часть 2;
        end;
        endif;
    endif;
@enduml
 */
/**
@startuml
title Алгоритм работы клиента часть 2
:Часть 1;
:Получение сообщения;
if(Размер сообщения получен?) then (Да)
    if (Число байтов сообщения < 2 ?) then (Да)
        : Выйти из цикла;
        end;
    else (Нет)
        :Считать из потока
        размер сообщения;
    endif;
else if (Число байт сообщения < размера сообщения?) then (Да)
        :Выйти из цикла;
        else(Нет)
        :Обработка сообщения;
        :Подтверждение получения сообщения серверу;
endif;
:ожидание срабатывания readyRead;
@enduml
 */
/**
@startuml
title Алгоритм работы при отключении клиента
start;
repeat:Работа клинта;
    while(Клинет отключился?) is(Да)
        :Передать сокет в очередь на удаление;
        :Вызвать slotDeleteSocket;
        end;
    endwhile(Нет)
@enduml
 */

namespace Ui {

class MainWindow;

}

/**
 * @brief The MainWindow class           класс клиента
 * @details                              получает данные от сервера.
 *                                       создает файл бд с присланным именем файла и таблицами header и data.
 *                                       открывает файл бд и записывает данные полученные от сервера в таблицу header и data
 */
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    /**
     * @brief on_pushButton_clicked     слот нажатия кнопки для подключения к серверу
     */
    void on_pushButton_clicked();
    /**
     * @brief on_lineEdit_returnPressed подключение к серверу при нажатии клавиши Enter
     */
    void on_lineEdit_returnPressed();


private:
    Ui::MainWindow *ui;
    /**
     * @brief d_socket                  сокет клиента
     */
    QTcpSocket *d_socket;
    /**
         * @brief data                  данные для отправки на сервер
         */
    QByteArray data;
    /**
         * @brief sendToServer          передать данные на сервер
         * @param status                статус о полном или не полном получении сообщения
         */
    void sendToServer(bool status);
    /**
     * @brief delay                     задержка для отправки подверждения о получении сообщения
     * @param n                         кол-во мсек
     */
    void delay(int n);
    /**
     * @brief d_nextBlockSize           размер следующего блока данных
     */
    quint16 d_nextBlockSize;
    /**
     * @brief d_db                      база данных для записи полученной информации
     */
    QSqlDatabase d_db;
    /**
     * @brief d_rowCount                количество строк в файле, который отправляет сервер
     */
    int d_rowCount;
    /**
     * @brief d_writeRowCount           количество строк, записанных клиентом
     */
    int d_writeRowCount = 0;
    Isi* d_isi;
    /**
     * @brief parseMessageTypeFile      обработать сообщение с типом file:
     * @param message                   сообщение
     * @return
     */
    bool parseMessageTypeFile(const QString &message);
    /**
     * @brief parseMessageTypeHeader    обработать сообщение с типом header:
     * @param message                   сообщение
     * @return
     */
    bool parseMessageTypeHeader(const QString &message);
    /**
     * @brief parseMessageTypeData      обработать сообщение с типом data:
     * @param message                   сообщение
     * @return
     */
    bool parseMessageTypeData(const QString &message);

public slots:
    /**
     * @brief slotReadyRead             слот обработки полученных данных
     */
    void slotReadyRead();
    /**
     * @brief slotError                 слот обработки ошибок
     */
    void slotError(QAbstractSocket::SocketError);
};

#endif // MAINWINDOW_H
